package Filters;

import java.io.UnsupportedEncodingException;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import FilesManagers.CantOpenFileException;

public class CharacterUnifier extends WordsFilter{

	private Charset charset;
	private CharsetDecoder decoder;
	private CharsetEncoder encoder;
	
	public CharacterUnifier(String biblioteca) throws CantOpenFileException{
		super(biblioteca,'1',',');
		this.charset = Charset.forName("ISO-8859-1");
	    this.decoder = charset.newDecoder();
	    this.encoder = charset.newEncoder();
		
		
	}
	
	/**
	 * 
	 * @param linea - String en mayuscula.
	 * @return String en minuscula
	 */
	public static String limpiarMayus(String linea){
		linea = linea.toLowerCase();
		return linea;
	}

	/**
	 * 
	 * @param lineaNueva - String en minuscula.
	 * @return String sin acentos del tipo �,�,�,etc
	 */
	private static String limpiarAcentos(String lineaNueva){
		
		
		//lineaNueva = lineaNueva.replace("ç","c");
		lineaNueva = lineaNueva.replace("á","a");
		lineaNueva = lineaNueva.replace("Á","a");
		lineaNueva = lineaNueva.replace("à","a");
		lineaNueva = lineaNueva.replace("ä","a");
		//lineaNueva = lineaNueva.replace("å","a");
		lineaNueva = lineaNueva.replace("â","a");
		lineaNueva = lineaNueva.replace('é','e');
		lineaNueva = lineaNueva.replace('É','e');
		lineaNueva = lineaNueva.replace('ë','e');
		lineaNueva = lineaNueva.replace('è','e');
		//lineaNueva = lineaNueva.replace('ê','e');
		lineaNueva = lineaNueva.replace('í','i');
		lineaNueva = lineaNueva.replace('Í','i');
		lineaNueva = lineaNueva.replace('ì','i');
		lineaNueva = lineaNueva.replace('ó','o');
		lineaNueva = lineaNueva.replace('ò','o');
		lineaNueva = lineaNueva.replace('Ó','o');
		//lineaNueva = lineaNueva.replace('ŏ','o');
		lineaNueva = lineaNueva.replace('ö','o');
		lineaNueva = lineaNueva.replace("ú","u");
		lineaNueva = lineaNueva.replace("ù","u");
		lineaNueva = lineaNueva.replace("Ú","u");
		lineaNueva = lineaNueva.replace("ñ","n");
		lineaNueva = lineaNueva.replace("ü","u");
		
		
		
		return lineaNueva.trim();
	}

	/**
	 * 
	 * @param linea - String en minuscula.
	 * @return String sin acentos del tipo &aacute;,&eacute;,&iacute;,etc
	 */
	private static String limpiarCodificaciones(String linea){
		
		linea = linea.replace("&aacute;","a");
		linea = linea.replace("&eacute;","e");
		linea = linea.replace("&iacute;","i");
		linea = linea.replace("&oacute;","o");
		linea = linea.replace("&uacute;","u");
		linea = linea.replace("&uuml;","u");
		/*En google la � la reemplaza con n , lo comprobe buscando ca�on , y obtuve resultados para ca�on y canon*/
		linea = linea.replace("&ntilde;","n");
		/*El resto no tiene relevancia, y no quiero que aparezcan*/
		linea = linea.replaceAll("&.*;"," ");


		return linea.trim();


	}
	/**
	 * 
	 * @param linea - String sobre el cual quiero hacer la limpieza
	 * @return String en minuscula y sin acentos.
	 */
	public static String limpiarMayusAcentosYCodif(String linea){
		
		linea= limpiarMayus(linea);
		linea= limpiarCodificaciones(linea);
		linea= limpiarAcentos(linea);
		return linea;
		
	}
	
	/**
	 * 
	 * @param linea - String sobre el cual quiero eliminar los espacios en blanco redundates
	 * @return  String sin con las palabras espaciadas en 1 solo caracter blanco
	 */
	public static String limpiarBlancosRedundantes(String linea){
		/*Para Eliminar los espacios de mas de un caracter entre palabras y los tabs*/
		while(linea.indexOf("\t")!=-1)linea = linea.replace("\t"," ");
		while(linea.indexOf("  ")!=-1)linea = linea.replace("  "," ");
		return linea;
	}
	
	
	/**
	 * @param linea - String que quiero estandarizar
	 * @param separadorNumerosEstandar - separador que quiero usar para estandarizar entre numero
	 * @return String con los separadores de numero estandarizados
	 * Si tengo 'numero separadorNumero numero' (sin espacios) unifico todo como numero/numero 
	 * */
	private String estandarizarSeparadorNumeros(String linea,String separadorNumerosEstandar){
	

		//String separadorNumerosEstandar = "/";
		String[] separadoresNumeros ={":","-","\\","(",")","=","[","]","%",",","+",";","#","?","¿"};
		//String[] separadoresNumeros ={":","-","\\","=","%",",","+",";","#"};
		String[] palabras = linea.trim().split(" ");
		Pattern patron;
		Matcher encaja=null;
		boolean encajo= false;
		
		String resultado="";
		for(int i=0; i< palabras.length; i++){
			if(!palabras[i].equals(" ") && !palabras[i].equals("")){
				encajo=false;
				//int j=0;
				//while(){
				for(int j=0; j<separadoresNumeros.length;j++){
					patron = Pattern.compile("([0-9]+)\\"+separadoresNumeros[j]+"([0-9]+)");
					encaja = patron.matcher(palabras[i].trim());
					if(encaja.find()){
						encajo=true;
						break;
					}
				}
				if(encajo){
					palabras[i] = encaja.group(1)+separadorNumerosEstandar+encaja.group(2);
					//System.out.println("-------------------"+palabras[i]);
				}
				resultado = resultado+" "+palabras[i];
			}
			
		}
		return resultado;
		
	}
	
	/**
	 * 
	 * @param linea - String.
	 * @return String sin caracteres como -,;,.,:,etc. 
	 * Se mantiene el caracter / .
	 * 
	 *  
	 */
	private String limpiarCaracteresInutiles(String linea){

		/*Por las pruebas que hice google unifica ciertos caractes el '-' , ':' y '/' los considera iguales si antes y despues tenemos numeros ej 17:05
		pero si tenemos palabras ej: materia:aburrida directamente lo considera como un caracter en blanco
		Habria que ver si queremos optimizar esto con Expresiones Regulares del tipo ([0-9]+)-([0-9]+) para numeros, etc */
		
		//String[] caracteresInutiles ={"-","—","_",":",";",".",",","\\","{","}","(",")","=","[","]","%",",","+",";","#","?","¿","`","'","!","¡","&","*","|","@","®","\"","·","•","^","º","ª","c","ß","ð","þ","æ","°","§","±","×","¹","²","³","«","»","£","©","ø","~"};
		
		
		/*for(int i=0; i<caracteresInutiles.length;i++){
			linea = linea.replace(caracteresInutiles[i]," ");			
		}*/
		Iterator<String> it = this.getListaPalabras().iterator();
		while(it.hasNext()){
			String simbolo = it.next();
			//System.out.println("Simbolo "+simbolo);
			while(linea.indexOf(simbolo)!=-1)linea = linea.replace(simbolo," ");
		}
		
		linea = linea.replace(","," ");
		linea = linea.replace("/"," ");
		//linea = linea.replace("¿"," ");
		//linea = linea.replace("®"," ");
		linea = linea.trim();

		return linea;


	}



	/*private String limpiarNumeros(String linea){

		linea = linea.replaceAll("([0-9]+)"," ");
		return linea;

	}*/

	private String unificarCodificacion(String p){
		
		
	    String s="";
	    String[]palabras = p.split(" ");
	    StringBuffer sb=new StringBuffer("");
	    CharBuffer cbuf;
	    java.nio.ByteBuffer bbuf;
	    for(int i=0;i<palabras.length;i++){
	    	String aux=palabras[i].trim();
		    try {
		        // Convert a string to ISO-LATIN-1 bytes in a ByteBuffer
		        // The new ByteBuffer is ready to be read.
		    	
		    	bbuf = encoder.encode(CharBuffer.wrap(aux));
		    
			        // Convert ISO-LATIN-1 bytes in a ByteBuffer to a character ByteBuffer and then to a string.
			        // The new ByteBuffer is ready to be read.
			      cbuf = decoder.decode(bbuf);
			      
			       
			        s = cbuf.toString();
			        
		    		//s = new String (p.getBytes(), "ISO-8859-1");
			        if(!aux.equals("")&& aux.equals(s)){
			        	sb.append(" ").append(s);
			        }/*else{
			        	System.out.println("&&&&&&& ERAN DIFERENTES "+aux+"  y "+s+"!!!!!!!");
			        	
			        }*/
			        
			        
			       
			       //return s;
		        
		        
		    } catch (CharacterCodingException /* UnsupportedEncodingException*/ e) {
		     	//System.out.println("!!!!!!!!!! No pude pasar a ISO-8859-1 el string "+aux+" !!!!!!!");
		     }
	    }
	    //System.out.println("!!!Del buffer saco "+sb.toString()+" !!!!!!!");
	    return sb.toString().trim();
		
	}
	
	@Override
	protected String filterWords(String lineaOrigen) {
		String linea=lineaOrigen.trim();
		linea = limpiarBlancosRedundantes(linea); 
		linea = limpiarMayusAcentosYCodif(linea);
		//linea = this.limpiarNumeros(linea); No se como vamos a manejar el tema de los numeros
		//linea = this.estandarizarSeparadorNumeros(linea,"/");
		linea = this.limpiarCaracteresInutiles(linea);
		linea = limpiarBlancosRedundantes(linea);
		linea = this.unificarCodificacion(linea);
		linea = this.limpiarCaracteresInutiles(linea);
		linea = limpiarBlancosRedundantes(linea);

		return linea.trim();
	}

	@Override
	protected void ordenarPalabras() {
		// TODO Apéndice de método generado automáticamente
		
	}





}